perm filename BR11.PAL[KL,SYS] blob sn#534206 filedate 1980-06-30 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00025 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	.SBTTL	DTE20 INITIALIZATION ROUTINE, 9-SEPTEMBER-75
C00005 00003	.SBTTL	ROUTINE TO READ THE EBUS VIA THE DTE20
C00007 00004	.SBTTL	ROUTINE TO EXECUTE DIAG FUNCTION VIA DTE20
C00009 00005	DIAGNOSTIC FUNCTION EXECUTE, FAST
C00011 00006	.SBTTL	ROUTINE TO WRITE 36 BITS TO THE EBUS
C00014 00007	.SBTTL	ROUTINE TO DO EBUS READ, THEN STORE DATA SOMEPLACE
C00016 00008	.SBTTL	MASTER RESET ROUTINE
C00021 00009	.SBTTL	CONTROL RAM ADDRESS ROUTINE
C00023 00010	.SBTTL	WCRAM ROUTINE
C00026 00011	$STRCH:	MOV	WREADY,R0	GET UNSPACED DATA
C00028 00012	.SBTTL	RCRAM ROUTINE
C00031 00013	15$:	MOVB	WREADY+1,-(R3)	ENDING UP
C00033 00014	$SQASH:	MOV	WREADY,R1	GET STRETCHED BITS 8-19
C00035 00015	.SBTTL	MICNUL & MICFIL C-RAM ROUTINES
C00036 00016	MICFIL, C-RAM FILL WITH ONES ROUTINE
C00037 00017	.SBTTL	WDRAM ROUTINE
C00038 00018	.SBTTL	RDRAM ROUTINE
C00040 00019	$DRAMAD: MOV	#DDRAM,R3	GET ADDRESS OF EBUS DATA
C00042 00020	WRITE THE IR
C00044 00021	.SBTTL	M-BOX CLOCK BURST ROUTINE
C00046 00022	.SBTTL	LOAD AR ROUTINE
C00049 00023	.SBTTL	MBOX PHASE ROUTINE
C00052 00024	.SBTTL	VMA, VMAH, PC & ADDRESS BREAK ROUTINE
C00054 00025		MOV	#WREADY+5,R1	NOW MOVE READ DATA
C00056 ENDMK
C⊗;
.SBTTL	DTE20 INITIALIZATION ROUTINE, 9-SEPTEMBER-75

DTEINI:	TST	$ONETM		;HAVE WE GONE THRU THIS ONCE BEFORE ?
	BNE	3$		;BR IF YES
	MOV	#DTEADR,R0

11$:	MOV	#16.,R2
	MOV	#.DELAY,R1
1$:	MOV	R0,(R1)+	;SETUP DTE20 INDIRECT ADDRESS POINTERS
	INC	R0
	INC	R0
	DEC	R2
	BNE	1$
3$:	SETFLG
	$ONETM

	MOV	#$STJRS,R0	;SETUP "JRST" START INSTRUCTION
	MOV	#$$STJRS,R1	;MUST BE IN STORAGE BECAUSE
	MOV	(R0)+,(R1)+	;THE JRST ADR IS VARIABLE
	MOV	(R0)+,(R1)+
	MOV	(R0)+,(R1)+

	MOV	#$PAGDFL,R0	;SETUP "DATAO PAG,0" DEFAULT ARGUMENT
	MOV	#PAGDFL,R1	;MUST BE IN STORAGE BECAUSE THE CURRENT
	MOV	(R0)+,(R1)+	;AC BLOCK SELECTION IS VARIABLE
	MOV	(R0)+,(R1)+
	MOV	(R0)+,(R1)+

	CLR	R0
	SETMPH			;SET M-BOX PHASE
	RTS	PC

$PAGDFL:WD36	7000,0040,0000	;LD'S & NO ST ACC
.EVEN

$STJRS:	I10	JRST,0,,0
.EVEN

$DTEBAS:MOV	.DELAY,R0
	EXIT
.SBTTL	ROUTINE TO READ THE EBUS VIA THE DTE20

;THIS IS THE ROUTINE TO READ 36 BITS FROM THE EBUS
;THE CALL REQUIRES THE DIAGNOSTIC FUNCTION TO BE EXECUTED
;TO BE IN REGISTER R0,RIGHT JUSTIFIED.
;CALLING SEQUENCE:
;	CALL-1:	MOV	#DIAG FUNCTION,R0
;	CALL:	DFRD

$DFRDT:	MOV	@$EMADR,R0	;PICKUP TRAILING PARAMETER
	ADD	#2,12(SP)	;SKIP RETURN

$DFRD:	JSR	PC,$KLCK1	;CHECK KL10 CLOCK RUNNING
	ASL	R0		;MAKE DIAG FCN IN CORRECT BITS
	SWAB	R0		;MAKE DIAG FCN IN CORRECT BYTE
	BIS	#DCOMST!DFUNC!DIKL10,R0 ;SET CORRECT DTE20 BITS
	MOV	R0,@.DIAG1	;EXECUTE THE FUNCTION
$DFXX:	WFZERO	DCOMST		;WAIT FOR DONE FLAG
	JSR	PC,$KLCK2	;RESTART CLOCK IF NECESSARY
	EXIT

$DFTIM:	CLR	TENRUN
	PMSG	<?DF TIMEOUT AT >
	MOV	R1,R0
	PNTOCT
	PMSG	<PC = >
	MOV	16(SP),R0		;GET ADDRESS OF CALL
$DFTMX:	TST	-(R0)
	PNTOCT
	JMP	$CNTLC

$ECTIM:	PMSG	<?CLK>

$DFTM1:	PMSG	< ERR AT >
	MOV	R1,R0
	BR	$DFTMX
.SBTTL	ROUTINE TO EXECUTE DIAG FUNCTION VIA DTE20

;THIS IS THE ROUTINE TO EXECUTE A NON-DATA
;DIAGNOSTIC FUNCTION.  THE CALL REQUIRES THE
;DIAGNOSTIC FUNCTION TO BE EXECUTED TO BE IN
;REGISTER R0,RIGHT JUSTIFIED

;CALLING SEQUENCE:
;	CALL-1:	MOV	#DIAG FUNCTION,R0
;	CALL:	DFXCT

;DIAGNOSTIC FUNCTION EXECUTE, TRAILING PARAMETER

$DXCTT:	MOV	@$EMADR,R0	;PICKUP TRAILING PARAMETER
	ADD	#2,12(SP)	;SKIP RETURN
	BR	$DFXCT

;DIAGNOSTIC FUNCTION EXECUTE, SINGLE STEP KL10 CLOCK

$DFSCLK:CLR	KLCLKR		;CLEAR KL10 CLOCK RUNNING
	MOV	#DCOMST!DFUNC!<SSCLK*1000>,@.DIAG1
	BR	$$DFX1

;DIAGNOSTIC FUNCTION EXECUTE

$DFXCT:	CMP	R0,#001		;KL10 CLOCK START FUNCTION ?
	BEQ	1$		;YES
	CMP	R0,#007		;ANY OTHER CLOCK CONTROL FUNCTION ?
	BGT	2$		;NO
	CLR	KLCLKR		;YES, CLEAR LOGICAL CLOCK RUN FLAG
	BR	2$
1$:	MOV	#-1,KLCLKR	;CLOCK START, SET LOGICAL CLOCK RUN FLAG
2$:	ASL	R0		;MAKE DIAG FCN IN CORRECT BITS
	SWAB	R0		;MAKE DIAG FCN IN CORRECT BYTE
	BIS	#DCOMST!DFUNC,R0 ;SET CORRECT DTE20 BITS
	MOV	R0,@.DIAG1	;EXECUTE THE FUNCTION
$$DFX1:	WFZERO	DCOMST		;WAIT FOR DONE
	EXIT			;RETURN
;DIAGNOSTIC FUNCTION EXECUTE, FAST

$DFXFST:ASL	R0		;DIAG FUNCTION TO CORRECT BITS
	SWAB	R0
	BIS	#DCOMST!DFUNC,R0
	MOV	R0,@.DIAG1	;EXECUTE THE FUNCTION
	BR	$$DFXDN

;KL10 CLOCK RUNNING CONTROLS

$KLCK1:	TST	KLCLKR		;KL10 CLOCK RUNNING ?
	BEQ	$KLCK4		;NO
	MOV	#DCOMST!DFUNC!<STPCLK*1000>,@.DIAG1
$$DFXDN:
$KLCK3:	WFZERO	DCOMST
$KLCK4:	RTS	PC

$KLCK2:	TST	KLCLKR		;WAS CLOCK RUNNING ?
	BEQ	$KLCK4		;NO
	MOV	#DCOMST!DFUNC!<STRCLK*1000>,@.DIAG1
	BR	$KLCK3

FFDEP:	DEP			;DTE20 DEPOSIT/EXAM BIT

;DIAGNOSTIC FUNCTION, WRITE IR

$DFWIR:	DFWRT			;THE LOAD AR FUNCTION IS ALREADY SETUP
	MOV	#DCOMST!DFUNC!<IRLOAD*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;STROBE DATA FROM AD TO IR
	EXIT
.SBTTL	ROUTINE TO WRITE 36 BITS TO THE EBUS

;THIS IS THE ROUTINE TO WRITE 36 BITS TO THE EBUS
;THE ROUTINE REQUIRES THAT THE ADDRESS OF THE DATA
;TO BE WRITTEN IS IN REGISTER R1.  THE DIAGNOSTIC
;FUNCTION WHICH DOES THE WRITE MUST BE RIGHT 
;JUSTIFIED IN REGISTER R0.THE DATA TO BE WRITTEN MUST
;BE IN 5 CONSECUTIVE BYTES AS FOLLOWS:
;	.BYTE	EBUS BITS 28-35
;	.BYTE	EBUS BITS 20-27
;	.BYTE	EBUS BITS 12-19
;	.BYTE	EBUS BITS 04-11
;	.BYTE	EBUS BITS 00-03

;CALLING SEQUENCE:
;	CALL-2:	MOV	#ADDR,R1
;	CALL-1:	MOV	#DIAG FCN,R0
;	CALL:	DFWRT

$DFWRT:	JSR	PC,$KLCK1	;KL10 CLOCK RUNNING ?
	PUSH	R1		;SAVE  DESTINATION FOR POSTERITY
	BIT	#1,R1		;DATA ON WORD BOUNDRY ?
	BEQ	2$		;YES
	MOV	#XXDAT,R5
	MOVB	(R1)+,(R5)+	;PUT BITS 28-35 INTO CORE WORD
	MOVB	(R1)+,(R5)+	;PUT BITS 20-27 INTO CORE
	MOV	-(R5),@.DAT3	;PUT BITS 20-35 INTO DTE20
	MOVB	(R1)+,(R5)+	;PUT BITS 12-19 INTO CORE WORD
	MOVB	(R1)+,(R5)+	;PUT BITS 4-11 INTO CORE WORD
	MOV	-(R5),@.DAT2	;PUT BITS 4-19 INTO DTE20
	MOVB	(R1)+,(R5)	;PUT BITS 0-3 INTO CORE WORD
	BIC	#177760,(R5)	;OFF TRASH
	MOV	(R5),@.DAT1	;BITS 0-3 INTO DTE20
1$:	MOV	#DIKL10!DSEND,@.DIAG1	;SET BIT TO DIAGNOSE KL10
	MOV	FFDEP,@.TENA1	;SET DEPOSIT BIT OF DTE20
	MOV	FFDEP,@.TENA2	;DO A PSEUDO DEPOSIT
	WFONE	DEXDON		;WAIT FOR A FLAG
	ASL	R0		;GET DIAG FCN IN BIT POSITION
	SWAB	R0		;GET DIAG FCN IN BYTE POSITION
	BIS	#DCOMST!DSEND!DIKL10!DFUNC,R0 ;SET DTE20 BITS
	MOV	R0,@.DIAG1	;EXECUTE THE DIAGNOSTIC FUNCTION
	POP	R0		;RESTORE WHERE GOT DATA
	JMP	$DFXX		;WAIT FOR DONE & EXIT

2$:	MOV	(R1)+,@.DAT3	;BITS 20-35
	MOV	(R1)+,@.DAT2	;BITS 4-19
	MOV	(R1),@.DAT1	;BITS 0-3
	BR	1$
.SBTTL	ROUTINE TO DO EBUS READ, THEN STORE DATA SOMEPLACE

;ENTER THIS ROUTINE WITH R0 CONTAINING DIAGNOSTIC FUNCTION TO EXECUTE
;AND R1 CONTAINING ADDRESS OF BUFFER WHERE DATA SHOULD BE PLACED

$DFRDMV:DFRD			;GO READ KL10 DATA
	PUSH	R1		;SAVE DESTINATION
	MOV	.DAT3,R0	;GET ADDRESS OF DTE20 REG
	MOVB	(R0)+,(R1)+	;DATA FROM DTE TO CORE
	MOVB	(R0)+,(R1)+	;DATA FROM DTE TO CORE
	MOVB	(R0)+,(R1)+	;DATA FROM DTE TO CORE
	MOVB	(R0)+,(R1)+	;DATA FROM DTE TO CORE
	MOVB	(R0)+,(R1)+	;DATA FROM DTE TO CORE
	POP	R0		;RESTORE REG R1
	EXIT

;DIAGNOSTIC FUNCTION WRITE, TRAILING PARAMETER

$DWRTT:	MOV	$EMADR,R5
	MOV	(R5)+,R1	;DATA ADDRESS TO R1
	MOV	(R5),R0		;DIAG FUNCTION TO R0
	ADD	#4,12(SP)	;RETURN OVER TRAILING PARAMETERS
	BR	$DFWRT

.SBTTL	MASTER RESET ROUTINE
;MASTER RESET DIAGNOSTIC FUNCTION LIST

LLIST:	.BYTE	STPCLK		;STOP CLOCK
	.BYTE	SETMR		;SET MASTER RESET
	.BYTE	STRCLK		;START CLOCK
	.BYTE	LDBRR		;LOAD BURST REGISTER RIGHT
	.BYTE	LDBRL		;LOAD BURST REGISTER LEFT
	.BYTE	LDDIS		;LOAD CLOCK DISTRIBUTION REGISTER
	.BYTE	LDCHK1		;LOAD PARITY CHECK REGISTER
	.BYTE	LDCHK2		;LOAD EBOX INTERNAL CHECK REGISTER
	.BYTE	LDCHAN		;INITIALIZE CHANNELS
	.BYTE	STPCLK		;STOP CLOCK
LLISTL==.-LLIST			;BUT THE LAST THREE ARE SPECIAL
	.BYTE	ENIOJA		;SET IR DECODE TO KL10 MODE
	.BYTE	76		;D.F. TO CONTROL EBUS REG
	.BYTE	LDMBXA		;LOAD MEMORY TO CACHE SELECTOR
.EVEN

;THIS IS A ROUTINE TO DO A MASTER RESET.

$MRESET:PUSH	R0		;SAVE REGISTERS
	TST	TENRUN		;PDP-10 PRESENTLY RUNNING ?
	BEQ	90$		;BR IF NOT
	TENSP			;STOP TEN
90$:	CLR	TENCLK		;AFTER THIS, THE 10 DOESN'T NEED CLOCK INTS
	CLR SWTDEP		; OR DATA SWITCHES ...
	CLR MONMODE		; ... OR MONITOR MODE (CLEAR FOR KA SIM)
	CLR MTTYOF
	CLR KASIM		;AND IS NO LONGER IN KASIM MODE
.IF DF CLKASB
	CLR TIMFLG		; ... OR TIME OF DAY
	CLR TMSFLG
.ENDC DF CLKASB
	MOV	#DRESET,@.DIAG2		;MASTER CLEAR THE DTE20
.IF DF %%QMP
;For QMP11, include INTRON in new DTE status
	MOV	#INTRON!DON10C!ERR10C!INT11C!PERCLR!DON11C!ERR11C,@.STDTE ;CLEAR DTE20 STATUS
.IFF
	MOV	#DON10C!ERR10C!INT11C!PERCLR!DON11C!ERR11C,@.STDTE ;CLEAR DTE20 STATUS
.ENDC
	DFWRTT			;WRITE TO CLOCK
	CLKDFL			;SET CLOCK TO DEFAULT
	LDSEL
	CLR	KLCLKR		;CLEAR KL10 CLOCK RUNNING
	MOV	#LLISTL,R1	;MUST EXECUTE TEN DIAG FUNCTIONS IN MR
	MOV	#LLIST,R2	;ADDRESS OF FUNCTIONS INTO R2
1$:	MOVB	(R2)+,R0	;FUNCTION TO R0 FOR THE EXECUTE CALL
	JSR	PC,$DFXFST	;EXECUTE THE DIAGNOSTIC FUNCTION
	DEC	R1		;DECREMENT COUNT OF # OF FUNCTIONS LEFT
	BNE	1$		;CONTINUE TILL DONE

	MOV	#3,R4		;SYNC MBOX NXM LOGIC
2$:	DFRDT			;TEST A CHANGE COMING L
	  162
	BIT	#BIT3,@.DAT3
	BEQ	3$		;ASSERTED, CONTINUE
	MOV	#DCOMST!DFUNC!<SSCLK*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;DO ONE MBOX CLOCK
	DEC	R4		;DONE 3 CLOCKS ?
	BGT	2$		;NO, TRY AGAIN

3$:	MOV	#DCOMST!DFUNC!<CECLK*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;CONDITIONAL EBOX CLOCK
	MOV	#DCOMST!DFUNC!<CLRMR*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;CLEAR MR

	MOVB	(R2)+,R0
	JSR	PC,$DFXFST	;SET IR DECODE

	MOVB	(R2)+,R0	;GET THE NEXT FUNCTION FROM THE LIST
	MOV	#WREADY,R1	;CLEAR A 36 BIT BUFFER FOR SENDING DATA
	MOV	R1,R5
	CLR	(R5)+		;CLEAR A WORK AREA
	CLR	(R5)+
	CLR	(R5)
	DFWRT			;WRITE 0'S TO EBUS & PREVENT SBUS RESET
	MOVB	#12,(R1)
	MOVB	(R2)+,R0	;GET NEXT DIAG FUNCTION
	DFWRT			;LOAD MEMORY TO CACHE SELECTOR
	POP	R0
	EXIT
.SBTTL	CONTROL RAM ADDRESS ROUTINE

$WWADR:	PUSH	R1		;SAVE R1
	TST	R0		;IF BIT 15 SET, AVOID MASTER RESET
	BMI	1$
	BIT	#BIT14,R0	;IF BIT 14 SET, SPECIAL RESET
	BEQ	2$
	JSR	PC,$SPCMR	;SPECIAL MASTER RESET
	BR	1$
2$:	MRESET
1$:	BIC	#BIT15!BIT14,R0	;CLEAR CONTROL BITS ANYWAY
	MOV	#WREADY+2,R5
	CLR	(R5)		;CLEAR A WORK AREA
	CLR	-(R5)

	PUSH	R0
	JSR	PC,99$		;GO LOAD EBUS BITS 00-05
	MOV	#LCRDAL,R0	;WILL WRITE BITS 00-04 OF CR-ADR
	DFWRT
	POP	R0		;GET COPY OF ORIGINAL CR-ADR
	SWAB	R0		;GET BITS 00-04
	ASR	R0		;TO LOW ORDER BITS
	ASR	R0		;OF R0.
	JSR	PC,99$		;GO LOAD EBUS BITS 00-05
	MOV	#LCRDAR,R0	;WILL WRITE BITS 5-10 OF CRADR
	DFWRT
	POP	R1		;RESTORE R1
	EXIT

99$:	BIC	#77,R0		;DEAL ONLY WITH 6 BITS
	MOVB	R0,WREADY+3	;MOV TO EBUS BITS 4 & 5
	SWAB	R0
	MOVB	R0,WREADY+4	;MOV TO EBUS BITS 0,1,2, & 3
	MOV	R5,R1		;ADDRESS FOR DFWRT
	RTS	PC
.SBTTL	WCRAM ROUTINE

WRLIST:	.BYTE	LCRAM1		;CRAM BITS 00-19
	.BYTE	LCRAM2		;CRAM BITS 20-39
	.BYTE	LCRAM3		;CRAM BITS 40-59
	.BYTE	LCRAM4		;CRAM BITS 60-79-EVEN
.EVEN

$WCRAM:	MOV	R1,R2		;GET COPY OF DATA ADDRESS
	WWADR			;GO AND WRITE C-RAM ADDRESS
	MOV	#3,R4		;FOUR LOOPS PER C-RAM WORD

1$:	MOV	#WREADY,R1	;GET HOLDING AREA
	MOVB	(R2)+,(R1)+	;REAL DATA TO HOLDING AREA
	MOVB	(R2)+,(R1)+
	MOVB	(R2),(R1)+

	TST	SIGNL		;SEE IF DESIRED BITS ON WORD BOUNDARY
	BEQ	3$		;AVOID RORING CODE IF YES

;THIS IS WONDERFUL RORING CODE

	TSTB	(R2)+		;MUST INCREMENT DATA ADDR PTR
	MOV	#4,R0		;FOUR SHIFTS IN THIS LOOP

2$:	MOV	#WREADY+3,R1	;POINT TO HOLDING AREA
	RORB	-(R1)		;SHIFT & INCLUDE "C" BIT
	RORB	-(R1)
	RORB	-(R1)
	DEC	R0		;DONE?
	BNE	2$		;LOOP BACK IF NO

;COMMON CODE

3$:	COM	SIGNL		;CHANGE BOUNDARY FLAG
	BIC	#177760,WREADY+2  ;ONLY 4 BITS COUNT
4$:	JSR	PC,$STRCH	;GO FILL IN EBUS SPACE
	MOVB	WRLIST(R4),R0	;CORRECT WRITE FUNCTION TO R0
	MOV	#WREADY,R1	;ADDRESS OF DATA
	DFWRT
	DEC	R4		;DONE ENTIRE RAM WORD?
	BGE	1$		;BR BACK IFNO

;CODE TO LOAD DISP 00-04

	MOVB	(R2),WREADY+4	;GET DATA FOR DISP
	ASRB	WREADY+4	;SHIFT DATA
	RORB	WREADY+3	;TO EBUS BITS
	ASRB	WREADY+4	;00-05
	RORB	WREADY+3
	DFWRTT			;WRITE
	WREADY			;DATA ADDRESS
	LCRAM5			;DIAG FUNCTION
	EXIT			;DONE
$STRCH:	MOV	WREADY,R0	;GET UNSPACED DATA
	MOVB	WREADY+2,WREADY+3 ;PUT C-RAM 0-3 BITS INTO CORRECT CORE
	CLR	R3		;NO JUNK LEFT IN R3
	SEC			;SET "C" BIT TO USE AS FLAG
1$:	MOV	#4,R5		;FOUR SHIFTS BETWEEN BLANKS
2$:	ROR	R3		;NEW DATA LEFT END OF DESTINATION
	BCS	3$		;IF FLAG FALLS OUT..DONE
	ROR	R0		;ROTATE SOURCE BITS RIGHT
	DEC	R5		;DONE 4 YET??
	BGE	2$		;BR IF NO

	ROL	R0		;REPAIR ANY DAMAGES 
	CLC			;ZERO THE "C" BIT
	ROR	R3		;AND ROLL ZEROES
	BR	1$		;AND CONTINUE

;GET HERE TO FINISH UP

3$:	CLC			;ZERO "C" BIT AGAIN
	ROL	R0		;BITS 4-7
	ROL	R0		;MUST BE CORRECTED
	MOV	R3,WREADY	;BITS 8-19 INTO CORE
	MOVB	R0,WREADY+2	;BITS 4-7 INTO CORE
	RTS	PC		;DONE

;SPECIAL BASIC MASTER RESET

$SPCMR:	PUSH	<R0,R1,R2>
	CLR	KLCLKR		;CLEAR KL10 CLOCK RUNNING
	MOV	#$SMRLST,R1	;COMMAND ADR TO R1
	MOV	#4,R2		;FOUR COMMANDS
1$:	MOV	(R1)+,@.DIAG1
	JSR	PC,$$DFXDN	;EXECUTE FUNCTION
	DEC	R2
	BNE	1$
	POP	<R2,R1,R0>
	RTS	PC

$SMRLST:.WORD	DCOMST!DFUNC!<SETMR*1000>
	.WORD	DCOMST!DFUNC!<STRCLK*1000>
	.WORD	DCOMST!DFUNC!<STPCLK*1000>
	.WORD	DCOMST!DFUNC!<CLRMR*1000>
.SBTTL	RCRAM ROUTINE

$RCRAM:	TST	R0		;IS R0 NEG
	BMI	1$		;READ CURRENT CR IF YES

	WWADR			;EXAMINE ADDRESS IN R0 IF HERE
	MOV	#DCOMST!DFUNC!<SECLK*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;CLOCK ADDRESS CONTENTS TO C.R.

1$:	MOV	#$BUFRC+10.,R3	;GET BUFFER ADDR FOR C-RAM CONTENTS
	MOV	#$RDLST,R4	;GET DIAG FUNCTION LIST

2$:	MOVB	(R4)+,R0	;DIAG FUNCTION
	DFRD
	MOV	#WREADY,R1	;DESTINATION OF READ/MOVE
	MOV	.DAT3,R0
	MOV	(R0)+,(R1)+
	MOV	(R0)+,(R1)+
	MOV	(R0),(R1)

	JSR	PC,$SQASH	;GO CLEAR OUT BLANKS
	MOV	#WREADY+3,R0	;ADDRESS OF DATA JUST READ
	MOVB	-(R0),-(R3)	;BITS 16-19 TO BUFFER
	TST	SIGNL2		;CHECK TRAFFIC LIGHT
	BNE	4$		;BR TO RORING IF WRONG BOUNDARY

3$:	MOVB	-(R0),-(R3)	;BITS 20-27 TO WORK AREA
	MOVB	-(R0),-(R3)	;BITS 28-35 TO WORK AREA
	COM	SIGNL2		;CHANGE SIGNAL
	BR	2$		;GET MORE DATA

4$:	ASLB	(R3)		;NEED TO FIX A HALF BYTE
	ASLB	(R3)
	ASLB	(R3)
	ASLB	(R3)
	PUSH	R0		;DON'T LOSE DATA ADDRESS
	MOV	#4,R0		;DO NEXT LOOP FOUR TIMES

10$:	MOV	R3,R2		;ADDRESS OF DATA TO R2
	ROLB	(R2)+		;SHIFT AND DON'T FORGET "C"
	ROLB	(R2)+
	ROLB	(R2)+
	ROLB	(R2)+
	DEC	R0		;ASSEMBLED COMPLETE HALF BYTE
	BNE	10$		;LOOP AGAIN IF NO
	POP	R0		;RETRIEVE DATA ADDRESS
	TSTB	(R3)+		;FIX DESTINATION ADDRESS
	TST	SIGNL3		;CHECK SIGNAL
	BNE	15$		;DONE IF MINUS
	COM	SIGNL3		;OTHERWISE CHANGE SIGNAL
	BR	3$		;CONTINUE
15$:	MOVB	WREADY+1,-(R3)	;ENDING UP
	MOVB	WREADY,-(R3)	;CRAM BITS 0-15 TO BUFFER
	COM	SIGNL3		;SIGNL3 TO ZERO
	COM	SIGNL2		;SIGNL2 TO ZERO
	DFRDT
	RCSPEC			;READ SPEC FIELD
	MOV	@.DAT2,R1	;GET DISP 03,04
	MOV	@.DAT1,R0	;GET DISP 00,01,02
	ROL	R1		;JUSTIFY IN R0
	ROL	R0
	ROL	R1
	ROL	R0

	BIC	#177740,R0	;CLEAR TRASH
	MOVB	R0,$BUFRC+12	;SAVE IN BUFFER
	MOV	#$BUFRC+2,R0	;RETURN DATA ADDRESS IN R0
	BIC	#5,(R0)		;CLEAR PARITY BITS
	BIC	#52525,-(R0)	;AND FIX ADDRESS
	EXIT			;DONE

$RDLST:	.BYTE	RCRAM1		;READ CRAM 0-19
	.BYTE	RCRAM2		;READ CRAM 20-39
	.BYTE	RCRAM3		;READ CRAM 40-59
	.BYTE	RCRAM4		;READ CRAM 60-79-EVEN
$SQASH:	MOV	WREADY,R1	;GET STRETCHED BITS 8-19
	MOV	WREADY+2,R2	;GET STRECHED BITS 0-7
	CLR	R0		;CLEAR A DESTINATION
	SEC			;SET A DONE FLAG
	ROR	R0		;AND ROLLIT INTO R0
1$:	MOV	#4,R5		;FOUR BITS PER GROUP
2$:	DEC	R5		;DONE A GROUP OF FOUR
	BLT	20$		;BRANCH IF NO
	ASR	R2		;ROTATE SOURCE BITS RIGHT
	ROR	R1		;ALL TWENTY OF THEM
	ROR	R0		;BEGIN WITH FIRST FLAG INTO R0
	BCC	2$		;IF FLAG FALLS OUT..DONE

;HERE TO FINISH UP

	ASR	R1		;MAKE LAST BLANKS
	ASR	R1		;GO VERY FAR AWAY
	MOV	R0,WREADY	;STORE RESULTS IN CORE
	MOV	R1,WREADY+2	;ALL DONE
	RTS	PC		;RETURN

20$:	ASR	R2		;HERE TO SHIFT AWAY
	ROR	R1		;THE PAIR
	ASR	R2		;OF BLANKS HIDDEN
	ROR	R1		;AMIDST THE REAL DATA
	BR	1$		;CONTINUE
.SBTTL	MICNUL & MICFIL C-RAM ROUTINES

;MICNUL, FILL C-RAM LOCATIONS WITH ZEROS

$MICNUL:MOV	R1,R2		;NUMBER OF WORDS TO R2
	MOV	R0,R3		;SAVE START ADDRESS
	BIS	#100000,R3	;BYPASS MR AFTER FIRST TIME
	MOV	#ZEROS,R1

1$:	WWADR			;WRITE C-RAM ADDRESS

	MOV	#3,R4
	MOVB	#LCRAM1,R0	;1ST FUNCTION IS A WRITE
	DFWRT

2$:	MOVB	FLST(R4),R0	;DIAG FUNCTION
	JSR	PC,$DFXFST
	DEC	R4
	BGE	2$		;ZERO ALL BITS

	INC	R3		;INCREMENT C-RAM ADDRESS
	MOV	R3,R0
	DEC	R2		;FINISHED ALL WORDS YET ?
	BGT	1$
10$:	EXIT			;YES

FLST:	.BYTE	LCRAM5
	.BYTE	LCRAM4
	.BYTE	LCRAM3
	.BYTE	LCRAM2
	.BYTE	LCRAM1
.EVEN
;MICFIL, C-RAM FILL WITH ONES ROUTINE

$MICFIL:MOV	R1,R2		;NUMBER OF WORDS TO R2
	MOV	R0,R3		;SAVE ADDRESS
	BIS	#100000,R3	;BYPASS MR AFTER FIRST TIME
	MOV	#TENMO,R1	;36 BITS OF ONES

1$:	WWADR			;WRITE C-RAM ADDRESS
	MOV	#4,R4

2$:	MOVB	FLST(R4),R0	;DIAG FUNCTION
	DFWRT
	DEC	R4		;DO ALL BITS
	BGE	2$

	INC	R3		;INCREMENT C-RAM ADDRESS
	MOV	R3,R0
	DEC	R2		;DONE ALL ADDRESSES YET ?
	BGT	1$
10$:	EXIT
.SBTTL	WDRAM ROUTINE

$WDRAM:	MOV	R0,R2		;COPY DRAM ADDRESS
	ROR	R0		;CHECK IF ODD OR EVEN
	BCC	1$		;BR IF EVEN
	JMP	ADRERR		;ADDRESS ERROR IF ODD

1$:	ROL	R0		;FIX ADDRESS
	PUSH	R1		;SAVE POINTER TO DATA
	DRAMAD			;GO WRITE DRAM ADDRESS
	POP	R3		;PUT POINTER TO DATA IN R3
	MOV	(R3)+,R1	;DATA INTO R1
	JSR	R5,DATEVE	;WRITE EVEN DATA
	MOV	(R3)+,R1	;DATA INTO R1
	JSR	R5,DATODD	;WRITE ODD DATA
	MOV	(R3),R1		;DATA INTO R1
	JSR	R5,DATCOM	;WRITE COMMON DATA
	EXIT
.SBTTL	RDRAM ROUTINE

$RDRAM:	PUSH	<R1,R0>		;SAVE R1,STORE DRAM ADDR ON STACK TOP
	CLR	R1		;R1 IS AN INDEX COUNTER
1$:	DRAMAD			;WRITE DRAM ADDRESS
	MOV	#DCOMST!DFUNC!<DRLTCH*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;STROBE DATA TO LATCHES
	DFRDT
	DRJ710			;FUNCTION TO READ J07,08,09,10
	MOV	@.DAT2,R0	;GET J DATA 7-10
	ASR	R0		;RIGHT JUSTIFY
	ASR	R0		;J-FIELD DATA
	BIC	#177700,R0	;CLEAR EXTRA
	MOVB	R0,RDRTMP(R1)	;SAVE DATA IN CORE
	INC	R1		;INCREMENT INDEX

	DFRDT
	DRAMAB			;FUNCTION TO READ "A" & "B" FIELD
	MOV	@.DAT2,R0	;GET A & B DATA
	ASR	R0		;RIGHT JUSTIFY
	ASR	R0		;IN R0
	BIC	#177700,R0	;CLEAR EXTRA
	MOVB	R0,RDRTMP(R1)	;STORE IN CORE
	INC	R1		;INCREMENT INDEX

;DECIDE IF THIS IS FIRST OR SECOND PASS

	CMP	R1,#3		;INDEX UP TO 3 YET??
	BGE	2$		;ON OUT IF YES
	POP	R0		;IF NO,GET DRAM ADDRESS
λβ↑C	R0		;GET ODD HALF OF EVEN/ODD PAIR
	BR	1$		;LOOP AGAIN

2$:	DFRDT
	DRJ1.4			;FUNCTION TO READ J01-J04
	MOV	@.DAT2,R0	;GET JDATA 01-04
	ASR	R0		;RIGHT JUSTIFY
	ASR	R0		;J1-J4 BITS
	BIC	#177760,R0	;CLEAR UNWANTED
	MOVB	R0,RDRTMP+4	;BIT SET TO CORE
	MOV	#RDRTMP,R0	;PASS BACK DATA ADDRESS IN R0
	POP	R1		;RESTORE R
	EXIT
$DRAMAD: MOV	#DDRAM,R3	;GET ADDRESS OF EBUS DATA
	MOV	R3,R4		;GET A COPY IN R4
	CMPB	(R4)+,(R4)+	;INCREMENT IT TO DDRAM+2
	MOV	R0,R2		;PUT ACTUAL ADDRESS IN R2
	COM	R2		;READY TO TEST ADDR BITS 0-2
	BIT	#700,R2		;MAKE THE TEST
	BEQ	1$		;BR IF ADDR IS 7XX

;CODE FOR NON 7XX ADDRESSES

	COM	R2		;WAS NOT 7XX,SO FIX ADDRESS
	ASL	R2		;JUSTIFY ADDRESS IN
	ASL	R2		;CORRECT BIT POSITION
	ASL	R2		;NEED THREE SHIFTS
	CLRB	(R4)+		;INCREMENT TO DDRAM+3
	MOVB	R2,(R4)+	;MOVE ADDR BITS 4-8 TO EBUS DATA
	SWAB	R2		;GET THE REST OF THE BITS
	MOVB	R2,(R4)		;MOVE ADDR BITS 0-3 TO EBUS DATA
4$:	JSR	PC,$SPCMR	;SPECIAL MASTER RESET
	JSR	R5,WIRAR	;GO TO DO THE ACTUAL WRITE
	EXIT

;CODE FOR 7XX ADRESSES

1$:	COM	R2		;FIX ADDRESS TO ORIGINAL STATE
	ROR	R2		;PUT LOW ORDER BIT IN "C" BIT
	BCS	2$		;"C" SET MEANS IR BIT 12 MUST=1

	CLRB	(R4)+		;NO "C" BIT MEANS IR BIT 12 MUST=0
	BR	3$		;GO TO MOVE ADDRESS TO EBUS DATA

2$:	MOVB	#200,(R4)+	;SET IR BIT 12=1
3$:	BIC	#340,R2
	MOVB	R2,(R4)+	;MOVE D-RAM ADDR TO EBUS BIT POSITION 7-11
	MOVB	#16,(R4)	;SET THE 7 FROM 7XX IN EBUS DATA
	BR	4$
;WRITE THE IR

WIRAR:	MOV	#DDRAM,R1	;EBUS DATA ALWAYS AT DDRAM
WIRAR1:	MOV	#LDAR,R0	;FUNCTION TO LOAD AR
	DFWIR
	RTS	R5

;NOW FOR COMMON LITTLE PIECES OF THE LOADING OF THE DRAM

DATCOM:	MOV	#LDRAM3,R0	;GET DIAG FUN TO WRITE COMMON
	ASL	R1		;JUSTIFY DATA FOR THE EBUS
	ASL	R1
	BR	CON2		;GO WRITE IT

DATODD:	MOV	#LDRAM2,$DDRMS	;FUNCTION FOR J-FIELD A & B
	MOV	#LDRJOD,R0	;FUNCTION FOR J-FIELD ODD
	BR	CON1		;GO
DATEVE:	MOV	#LDRAM1,$DDRMS	;FUNCTION FOR J-FIELD A & B
	MOV	#LDRJEV,R0	;FUNCTION J-FIELD EVEN
CON1:	ASL	R1		;JUSTIFY PIECE I'M
	ASL	R1		;INTERESTED IN FOR J-DATA FIELDS
	PUSH	R1		;SAVE DATA TO BE SENT
	JSR	R5,CON2		;WRITE J-DATA
	POP	R1		;GET DATA AGAIN
	SWAB	R1		;NOW I'VE GOT A & B
	MOV	$DDRMS,R0	;GET CORRECT DIAG FUNCTION, & WRITE

CON2:	MOVB	R1,DDRAM+2	;R1 ALWAYS HAS THE DATA
	MOV	#DDRAM,R1	;I ALWAYS PUT IT IN DDRAM
	DFWRT
	RTS	R5		;NOW WRITE

;CLOCK DEFAULT PARAMETER ADDRESS

$CLKPRM:MOV	#CLKDFL,R0	;PUT ADDRESS IN R0
	EXIT
.SBTTL	M-BOX CLOCK BURST ROUTINE

$BURST:	CLR	KLCLKR		;CLEAR KL10 CLOCK RUNNING
	MOV	#$STDAT,R1	;WORD POINTER TO R1
	MOV	R0,R2		;BURST COUNT TO R2
	BIC	#177600,R2	;SAVE LOWER 7 BITS
	ROL	R0
	SWAB	R0
	CLR	R3
	BISB	R0,R3		;# OF 128. CLOCK MULTIPLES
	BEQ	2$		;NONE, DO BURST

1$:	MOV	#DCOMST!DFUNC!<STPCLK*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;CLEAR BURST MODE
	CLR	(R1)
	MOV	#LDBRR,R0
	DFWRT			;CLEAR BURST REG RIGHT
	MOV	#10,(R1)
	MOV	#LDBRL,R0
	DFWRT			;LOAD BURST REG LEFT
	MOV	#DCOMST!DFUNC!<BRCLK*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;BURST 128 CLOCKS
	DEC	R3		;ANY MORE ?
	BGT	1$		;YES, DO 128 MORE

2$:	MOV	#DCOMST!DFUNC!<STPCLK*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;CLEAR BURST MODE
	MOV	R2,R3		;NUMBER LEFT TO DO
	BIC	#177760,R2
	MOV	R2,(R1)
	MOV	#LDBRR,R0
	DFWRT			;LOAD BURST REG RIGHT
	SR	R3,4
	MOV	R3,(R1)
	MOV	#LDBRL,R0
	DFWRT			;LOAD BURST REG LEFT
	MOV	#DCOMST!DFUNC!<BRCLK*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;BURST THE CLOCK
	EXIT
.SBTTL	LOAD AR ROUTINE

; ROUTINE TO LOAD THE AR WITH AN INSTRUCTION TO BE EXECUTED.
; GETS THE MICROCODE TO THE HALT LOOP, AND THEN LINES UP THE
; MBOX PHASE CHANGE TIMING WITH EBOX SYNC BEFORE LOADING
; THE AR.  THE LATTER IS NECCESSARY IN ORDER TO MAKE INSTRUCTION
; EXECUTION REPEATABLE AT THE CLOCK TICK LEVEL FOR "TRACE" AND
; FOR THE MBOX DIAGNOSTIC.

$LODAR:	MOV	R0,R3		;SAVE DATA POINTER
	MOV	#DCOMST!DFUNC!<CLRRUN*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;STOP EXECUTION
	MOV	#177,R0
	BURST			;RUN CLOCK FOR FIXED PERIOD
	MOV	#DCOMST!DFUNC!<CECLK*1000>,@.DIAG1
	JSR	PC,$$DFXDN	;GET EBOX CLOCK FALSE
	BIT	#HALTLP,@.DIAG1
	BNE	1$		;IF AT HALT LOOP
3$:	EXITERR

; NOW CALL ROUTINE TO GET MBOX IN PHASE

1$:	JSR	PC,$MBPHS
	BCC	2$		;BR IF ALL OK
	BR	3$

2$:	MOV	R3,R1
	MOV	#LDAR,R0
	DFWRT			;LOAD AR
	EXIT

; SETMPH EMT ROUTINE TO SELECT WHICH MBOX PHASE TO SYNC UP TO
;DURING THE LODAR PROCESS. R0 SELECTS ONE OF FOUR PLACES TO SYNC.
; R0 = 0, A CHANGE COMING; R0 = 1, HALFWAY TWIXT A AND B
; R0 = 2, B CHANGE COMING; R0 = 3, HALFWAY TWIXT B AND A.

$SETMPH:MOV R0,$STODD		;SAVE FOR HALF-PHASE TEST
	BIC #BIT0,R0		;CLR ODD-EVEN BIT
	MOV $STMTB(R0),$MPHDF	;SET DF VALUE FOR A OR B CHANGE
	MOV $STMT1(R0),$MPHMK	;SET BIT MASK FOR A OR B CHANGE
	EXIT

$STMTB:	162			;A CHANGE COMING DF
	163			;B CHANGE COMING DF

$STMT1:	10			;A CHANGE COMING BIT MASK
	400			;B CHANGE COMING BIT MASK
.SBTTL	MBOX PHASE ROUTINE

; ROUTINE TO PHASE THE MBOX WITH THE EBOX HALT LOOP.
; MICROCODE ASSUMPTIONS: THE HALT LOOP IS TWO INSTRUCTIONS
;	THE FIRST IS AT AN EVEN ADDRESS AND HAS T=3T (these used to be labeled
;	THE SECOND IS AT AN ODD ADDRESS AND HAS T=2T  backwards)
; THIS CODE LOOKS FOR THE INTERSECTION OF THE EVEN ADDRESS,
; CLK SYNC TRUE, PHASE CHANGE COMING TRUE, AND THE SELECTED
; PHASE (A OR B CHANGE COMING). THE LATTER IS CHOSEN BY
; THE "SETMPH" EMT.

$MBPHS:	MOV	#20.,R2		;SET TIMOUT VALUE
1$:	MOV	#1,R1		;SET TICK COUNTER
	DFRDT
	102
	BIT	#BIT2,@.DAT3	;BIT 33, CLK SYNC H
	BEQ	41$		;FALSE, TRY 1 CLOCK

	DFRDT
	144
	BIT	#BIT14,@.DAT2	;BIT 5, CR ADR 10 H
	BNE	42$		;ODD, TRY 2 CLOCKS

	DFRDT
	164
	BIT	#BIT5,@.DAT3	;BIT 30,PHASE CHANGE COMING L
	BNE	45$		;FALSE, TRY 5 CLOCKS

	MOV $MPHDF,R0		;used to be MOVB  -- jbr 4/27
	DFRD
	CLR R0
	BIT $MPHMK,@.DAT3	;EITHER A OR B CHANGE COMING L used to be bitb --jbr
	BEQ 2$			;TRUE, EXIT
	MOV	#10.,R0		;NEED 10 CLOCKS
2$:	BIT	#BIT0,$STODD	;WANT HALFWAY BETWEEN?
	BEQ	3$		;BR IF NOT
	ADD	#5,R0		;FIVE MORE TICKS THEN
3$:	BURST			;DO THIS BURST:0,5,10, OR 15
	CLC
	RTS	PC		;WE'RE THERE

45$:	ADD	#3,R1		;MAKE IT FOUR
42$:	INC	R1		;MAKE IT TWO OR FIVE
41$:	MOV	R1,R0
	BURST			;DO ONE TWO OR FIVE
	DEC	R2		;COUNT TIMEOUT
	BNE	1$
	SEC
	RTS	PC		;TOOK TOO LONG, ERROR
.SBTTL	VMA, VMAH, PC & ADDRESS BREAK ROUTINE

;ROUTINE TO READ ONE OF 4 REGISTERS ON THE VMA BOARD.
;ROUTINE RETURNS WITH R0 POINTING TO A 36 BIT WORD WITH
;THE DESIRED DATA JUSTIFIED AT BIT 35

$DFVMH:	MOV	#DPVMHD,R0	;FUNCTION TO READ VMA HELD
	BR	$DFPC1
$DFPC:	MOV	#DPPC,R0	;FUNCTION TO READ PC
$DFPC1:	MOV	#3,R5
	MOV	#273,R4		;MASK FOR REGISTER OFFSET FROM BIT 35
	BR	$VMPC
$DFVMA:	MOV	#DPVMA,R0	;DIAG FUNCTION TO READ VMA
	BR	$VMPC1
$DFADB:	MOV	#DPADB,R0	;DIAG FUNCTION TO READ ADDRESS BREAK
$VMPC1:	MOV	#356,R4
	CLR	R5
$VMPC:	PUSH	R0
	MOV	#4,R2		;FOUR READS PER REGISTER
	MOV	#VMADAT,R1	;FIRST CLEAR ENTIRE 36-BIT BUFFER
	CLR	(R1)+
	CLR	(R1)+
	CLR	(R1)+

1$:	MOV	#WREADY,R1	;PUT DFRD DATA HERE
	DFRDMV
	MOV	#5,R0		;MASK RECEIVED DATA, FIVE BYTES WORTH
2$:	BICB	R4,(R1)+
	DEC	R0
	BGT	2$
	MOV	#WREADY+5,R1	;NOW MOVE READ DATA
	MOV	#VMADAT+5,R0	;TO VMA REGISTER DATA
	BISB	-(R1),-(R0)
	BISB	-(R1),-(R0)
	BISB	-(R1),-(R0)
	BISB	-(R1),-(R0)
	BISB	-(R1),-(R0)
	ROLB	(R0)+		;AND NOW SHIFT 35 BITS
	ROLB	(R0)+		;BY ONE BIT
	ROLB	(R0)+
	ROLB	(R0)+
	ROLB	(R0)+

	DEC	(SP)		;CREATE NEXT DIAG FUNCTION
	MOV	(SP),R0		;TAKE IT OFF THE STACK
	DEC	R2		;DONE FOUR FUNCTIONS YET?
	BGT	1$		;BR IF MORE TO DO

;ALL DONE READING DATA, NOW JUSTIFY CORRECTLY FOR THE RETURN MACHINE

3$:	MOV	#VMADAT+5,R0	;MUST CORRECT BY OFFSET AMOUNT
	RORB	-(R0)
	RORB	-(R0)
	RORB	-(R0)
	RORB	-(R0)
	RORB	-(R0)
	DEC	R5		;DONE YET?
	BGT	3$		;BR IF NO

;OFFSET MAY ORIGINALLY NEED TO BE GREATER THAN 0 IF
;VMA DIAG MIXERS NOT RIGHT JUSTIFIED AT EBUS BIT 35

4$:	POP	R0
	MOV	#VMADAT,R0
	EXIT